home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OctaMED Sound Studio 1
/
OctaMED SoundStudio V1.iso
/
soundstudio v1
/
programmers
/
proplayer.doc
< prev
next >
Wrap
Text File
|
1996-06-18
|
16KB
|
438 lines
INTRODUCTION TO OCTAMED PLAYER ROUTINES
=======================================
This drawer contains the material, which is required for using OctaMED
music in your own programs. You are allowed to freely use these routines in
your own non-commercial programs. For commercial products, you will have to
licence the routines. (See the files ReadMe.doc and Licence.doc for the
details.)
You have basically two choices - you can either incorporate the player
routine (written in assembler) to your program, or you can use the provided
external player libraries.
1. Embedded player routines (proplayer/pro8player/promixplayer)
These are the most often used routines. They are usually the best choice
for embedded game music, module player programs etc. Easy switches are
provided for turning off unnecessary features. As the assembler source is
provided, you can modify the code or add hooks to suit your specific
purpose. The rest of this document contains instructions for the proplayer
routines.
2. Player libraries (medplayer.library/octaplayer.library/
octamixplayer.library)
These are shared libraries that any application program may call. (Only one
task can be using them at a time, though.) The libraries contain basically
the same functionality as proplayer routines, but no tailoring can be made.
An obvious advantage is that library upgrades are transparent to your
application. The user can simply replace the libraries. See the file
Library.doc for details on using the libraries.
Note: medplayer.library and octaplayer.library are located in the LIBS
drawer of this disk.
Note: If you need a feature that currently does not exist, send us your
exact requirements, and we'll do our best to help you.
Instructions for using "proplayer.a", the stand-alone playroutine.
===========================================================================
"proplayer" is a piece of code which is linked with your program and plays
four channel MED and OctaMED modules (with optional MIDI).
"proplayer" contains the following routines:
InitPlayer
RemPlayer
PlayModule
ContModule
StopPlayer
SetTempo
The arguments are passed in registers, and return values are returned in d0.
These routines will trash registers d0-d1 and a0-a1.
And now the descriptions of each one:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
InitPlayer -- initialize everything
Before you can call the other functions, you must call this function.
It allocates the audio channels, timer, serial port (if MIDI) etc...
ARGUMENTS: none
RETURNS: 0 if everything is ok, otherwise something failed.
If something failed, you can still call the other
routines - they just don't do anything.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RemPlayer -- return everything back
Call this when your program exits. It frees the audio channels, timer,
serial port etc.
ARGUMENTS: none
RETURNS: nothing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PlayModule -- start playing a module
When you want to start playing, call this routine.
ARGUMENTS: a0 = pointer to the module. See below for instructions
how to obtain the pointer.
RETURNS: nothing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
StopPlayer -- stop playing
ARGUMENTS: no arguments
RETURNS: nothing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ContModule -- continue playing
This routine continues playing the module from the point it was stopped.
ARGUMENTS: a0 = pointer to the module
RETURNS: nothing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SetTempo -- set the playback tempo
(This routine has not much use.)
ARGUMENTS: d0 = new tempo (1 - 240)
RETURNS: nothing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"proplayer.a" is the source code of the music routine. It contains stuff
that may be unnecessary for your purposes, just taking time and memory.
There are some "switches" at the beginning of the source, that allow you
to turn off features you don't need. They are:
MIDI If only the Amiga audio channels are used, set this to 0.
AUDDEV For some purposes, you may want to disable the code that
allocates the audio channels using "audio.device", e.g.
in a non-multitasking environment. Normally this should
be 1.
SYNTH If synth/hybrid sounds are not in use, this can be set to
zero.
CHECK This does some checkings to ensure that several values are
correct (e.g. is the sample in memory, no Amiga effects on
MIDI-tracks etc..). If you know that the song is correct,
you can safely turn the checks off.
RELVOL If you don't need the "relative volume", this can be zero.
IFFMOCT If the song doesn't contain multi-octave IFF samples
this can be zero.
HOLD This turns off the hold/decay features.
PLAYMMD0 If set, the play routine will also handle old MMD0 type
modules. Useful for player programs.
FASTMEMPLAY If you don't need FastMem playing, you can set this to 0
to save some code space.
AURA Aura output can be enabled by using this flag. (The file
"aura.a" must exist.)
"proplayer.a" also supports multi-modules. It defines a UWORD modnum
(in assembler: _modnum). Set this variable to the number of the song
you want to play before calling PlayModule (0 is the first, 1 is the
second song etc..). For example:
#include "proplayer.h" /* defines 'modnum' */
...
modnum = 1; /* Play the second module */
PlayModule(module);
...
Assembler:
xref _modnum
xref _PlayModule
...
move.w #1,_modnum
lea _module,a0
jsr _PlayModule(pc)
...
FastMem Playing
===============
It's now possible to play samples from the fast memory (also allowing long
samples and odd repeat offset/length). For this purpose, two other UWORDs
are defined in the routine: _fastmemplay must be set to 1 in order to
activate this feature. Also, you can also change the buffer size of FastMem
playing with the _fmp_buffsize symbol. Buffer size must be divisible by 4
and no more than 400. (Default: 64).
Timing
======
If you need vertical blanking timing, you can set VBLANK to 1 and CIAB to 0.
In normal use this is not recommended (because of the 16 % difference in
playing speed with NTSC and PAL Amigas), but if tight synchronization to
vertical blanking (e.g. in most demos/games) is required, VBLANK can be
used.
For VBlank timing, the song has to be composed with primary tempo of about
33. The primary tempo cannot be changed with command F. Only the secondary
tempo control can be used (command 9).
Assembling
==========
"proplayer.a" can be assembled by using HiSoft's Devpac Assembler without
changes. Other assemblers may need some small changes to work correctly
(mostly because the directives they support may be slightly different). If
you're working on a linker environment (e.g. programming in C), you've to
include the resulted "proplayer.o" in your .lnk-file.
===========================================================================
And how to get some music?
You have two ways to get the music:
1. Include the module in your final executable.
2. Save the module as a separate disk file and load it when needed
(this is probably the best way if you have more than one song, and
you don't want to use multi-modules).
First I cover the first method:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Including the module in your final executable:
There's a utility, Objconv, which loads the module and dumps it into an
object file. Here's an example how to use it:
- Assemble 'reloc.a' to 'reloc.o'.
- Save the song as a module
- Use Objconv e.g. objconv medmodule mod.o
- Objconv requests the symbol name, enter "song" (without "'s), for example.
- Now there's a file 'mod.o'. Link this file, and the file 'reloc.o'
with your program.
- In your program, you define the module:
#include "proplayer.h"
...
extern struct MMD0 far song;
You must relocate the module before it's used. Do this only once!
This is done by
RelocModule(&song);
RelocModule expects the argument in stack, so use __stdargs, if you've
turned registerized parameters on.
In assembler, you'd do exactly in the same way, except:
xref _song
xref _RelocModule
xref _PlayModule
... (assuming all init stuff is here)
lea _song,a0
move.l a0,-(sp) ;push into stack
jsr _RelocModule(pc)
addq.l #4,sp ;reset stack pointer
lea _song,a0 ;this is passed in register a0
jsr _PlayModule
...
Note: if you've got an assembler that supports 'incbin' directive or
equivalent, you can use it instead of Objconv. Relocation is required in
any case.
And the second method (loading modules from disk):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
File "loadmod.a" contains four routines:
LoadModule/LoadModule_Fast
UnLoadModule
RelocModule
RequiredPlayRoutine
You usually need only the first two of them. RelocModule is used by
LoadModule.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LoadModule/LoadModule_Fast -- loads a module from disk
This function loads a module from disk. Note that relocation is done
automatically, so you must not RelocModule() a module obtained by using
this routine.
Note: LoadModule_Fast is new as of OctaMED Soundstudio. OctaMED Soundstudio
sets a flag in the main MMD structure if the module can be always loaded
into fast RAM (i.e. if it uses mixing, only MIDI or 8-ch mode). If this
flag is set, both routines load the module into fast RAM. LoadModule_Fast
always loads the module into fast RAM, you need to use the FastMemPlay
feature to play 4-channel or 5-7 channel modules in that case.
ARGUMENTS: a0 = pointer to file name
RETURNS: d0 = pointer to the module, if something failed: 0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UnLoadModule -- free the module from memory
Frees the module. Remember to StopPlayer() before you unload the module
that is currently playing. Also remember to free all modules you've loaded
before you exit the program.
ARGUMENTS: a0 = pointer to the module (may be 0)
RETURNS: nothing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RequiredPlayRoutine -- find out which routine is required for this module
Checks the flag bits in the module to find out which playing routine
you should use. If you can't/don't want to support the playing routine
this function tells you, you had better refrain from playing the module
altogether, rather than using a wrong routine.
ARGUMENTS: a0 = pointer to the module (may be 0, in which case this
routine returns zero).
RETURNS: One of these values:
0 = use 4 channel routine (proplayer), or no module
1 = use 5-8 channel routine (pro8player)
2 = use mixing routine (promixplayer)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FastMemPlayRecommended -- should FastMemPlay used...?
In addition to playing modules from Fast RAM, FastMemPlay removes some
restrictions: the sample length limitation of 131072 bytes, and loop
granularity of 2 bytes. This routine checks whether the module uses
either of these extensions. If it returns TRUE, you should activate
FastMemPlay in order to be able to fully reproduce the module. If FALSE
is returned, the module plays perfectly even without FastMemPlay (if it's
in Chip RAM). Note: If at all possible, you should not keep FastMemPlayed
modules in Chip memory; they play much more efficiently from Fast RAM.
ARGUMENTS: a0 = pointer to the module (may be 0)
RETURNS: 0 = plays perfectly without FastMemPlay
1 = may not play perfectly without FastMemPlay
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
===========================================================================
REMEMBER: All functions expect the arguments in registers. This is
automatically (??) handled by you when you program in
assembler, but it is not automatically handled when
you're programming in C.
If you have SAS/C V5 or later, this is done automatically if you include
"proplayer.h" in all your code modules which call proplayer. If you have a
compiler which doesn't support argument passing in registers, then you have
to write the stub routines in assembler.
See also the small example sources.
File formats
============
The playing routines can be used to play all MMD formats saved by OctaMED
or late versions of MED. (Set PLAYMMD0 for MMD0 support.) The currently
supported formats are MMD0, MMD1, MMD2, MMD3.
MMD3?
=====
Although not mentioned in OctaMED itself, modules using mixing are saved
using the MMD3 format, which is identical to MMD2. The reason for this is
that old module players might choke if attempting to load a module that
uses mixing. *HOWEVER* MMD3 does NOT imply mixing!! You must always check
the required play routine with RequiredPlayRoutine, even with MMD3 modules.
MMD3 supporting programs should just be aware of the new Soundstudio mixing
mode, and fail if they can't/don't want to support it.
===========================================================================
pro8player.a
~~~~~~~~~~~~
"pro8player.a" is the play-routine for OctaMED 5 - 8 channel songs. This
can be used exactly in the same way as "proplayer.a". The functions just
have slightly different names:
InitPlayer8
RemPlayer8
PlayModule8
ContModule8
StopPlayer8
modnum8
Note that this player have some restrictions, as opposed to "proplayer.a".
They're listed in OctaMED documents. It also takes quite a lot of processor
time, depending on how many splitted channels there are.
You can use the same RelocModule() and (Un)LoadModule() routines with
5 - 8 channel songs.
The eight channel player has a byte flag _hq (assembler)/hq (C), which
controls the HQ mode. Set this to 1 prior to calling PlayModule8 to
activate the HQ mode.
===========================================================================
promixplayer.a
~~~~~~~~~~~~~~
This is the player routine for OctaMED Soundstudio modules using the 1-64
Ch mixing mode. Although it's internally rather complex, it should be as
easy to use as the other two routines. The functions are analoguous to the
other routines, their names are:
InitPlayerM
RemPlayerM
PlayModuleM
ContModuleM
StopPlayerM
However, a difference exists: PlayModuleM does some memory allocations for
mixing buffers, echo buffers etc. It returns a success value in D0. If the
return value is zero, the playing has been started successfully. Otherwise
a memory allocation error has occurred.
This player routine has several user-settable variables (C users should
omit the leading underscore):
(UWORD) _modnumm Module number, as in other routines.
(ULONG) _mixbuffsize Desired mixing buffer size (must be divisible
by 4!). [default 1024]
(ULONG) _mixfreq Desired mixing frequency in Hz (values below 1000
are not recommended, nor are values exceeding the
maximum output frequency depending on the screen
mode). Max. value 65535. [default 15000]
(UBYTE) _mix14bit If set, uses 14-bit output (otherwise 8-bit).
[default set]
IMPORTANT: This routine uses utility.library 32-bit math functions, and
therefore requires Kickstart V36 or later.
The actual mixing routine is located in a different file (med-mixasm.a).
You should set the flags provided in that file according to your desired
target processor (68000, 68020+ or both). I have to admit that the 68000
is usually far too slow for mixing, though, but this option is available
so that A500 owners can't complain... You have been warned.
The SUPPORT_000 and SUPPORT_020 flags work as follows:
Only SUPPORT_000 set:
Works with all processors. With 68020 or higher not as fast as
it could be.
Only SUPPORT_020 set:
Does not work with 68000/010. Optimized for 68020+.
Both flags set:
Works with all processors. Uses the optimal routine. Consumes
about 3 kilobytes more memory.
Med-mixasm.a also provides an optional smoothing routine. As the smoothing
routine is provided mainly for recording to disk (not supported by the
external playing routines), it's probably not useful (except for 68060
owners...?) due to the fact that it's very slow. Set the SUPPORT_SMOOTH
flag if you want to use it. Also, you have to call the _MixSmooth routine
(D0 = 0 or 1 for off/on) to turn the smoothing on.
===========================================================================